//
//  MPGraphView.m
//
//
//  Created by Alex Manzella on 18/05/14.
//  Copyright (c) 2014 mpow. All rights reserved.
//

#import "MPGraphView.h"
#import "UIBezierPath+curved.h"
#import "CustomChartView.h"

@implementation MPGraphView

+ (Class)layerClass {
    
    return [CAShapeLayer class];
}


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.layer.masksToBounds = YES;
        self.backgroundColor = [UIColor clearColor];
        //        _xPositions = [NSMutableArray array];
        //        _yPositions = [NSMutableArray array];
        currentTag=-1;
    }
    return self;
}


- (void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    
    if (self.values.count && !self.waitToUpdate) {
        
        //        ((CAShapeLayer *)self.layer).fillColor=[UIColor clearColor].CGColor;
        ((CAShapeLayer *)self.layer).strokeColor = self.graphColor.CGColor;
        ((CAShapeLayer *)self.layer).path = [self graphPathFromPoints].CGPath;
        ((CAShapeLayer *)self.layer).lineWidth=self.lineWidth ? self.lineWidth : 1;
    }
}


- (UIBezierPath *)graphPathFromPoints{
    
    BOOL fill = self.fillColors.count;
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    for (UIButton *button in self.buttons) {
        [button removeFromSuperview];
    }
    
    self.buttons = [[NSMutableArray alloc] init];
    
    for (NSInteger i = 0;i < points.count;i++) {
        
        CGPoint point = [self pointAtIndex:i];

//        if (!point.x) {
//            point.x = 0;
//        }
//        else if (!point.y) {
//            point.y = 0;
//        }
        
        if(i == 0)
            [path moveToPoint:point];
        
        if (_showPoints) {
            MPButton *button = [self customButtonWithIndex:i center:point];
            [self addSubview:button];
            button.transform = CGAffineTransformMakeScale(1, 1);
            [self.buttons addObject:button];
        }
        
        [path addLineToPoint:point];
    }
    
    if (self.curved) {
        path = [path smoothedPathWithGranularity:20];
    }
    
    if(fill){
        CGPoint last  = [self pointAtIndex:points.count-1];
        CGPoint first = [self pointAtIndex:0];
        [path addLineToPoint:CGPointMake(last.x,self.height)];
        [path addLineToPoint:CGPointMake(first.x,self.height)];
        [path addLineToPoint:first];
    }
    
    if (fill) {
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = self.bounds;
        maskLayer.path = path.CGPath;
        gradient.mask = maskLayer;
    }
    return path;
}

- (CGPoint)pointAtIndex:(NSInteger)index {
    
    MPGraphValuesRange value = [MPPlot rangeForValues:self.values];
    CGFloat space = (self.frame.size.width-40)/MAX((points.count-1), 1);
    if (value.max == value.min && value.max == 0) {
        return CGPointMake(20+(space)*index, self.height-5);
    }
    else {
//        return CGPointMake(20+(space)*index,
//                           self.height-((self.height-PADDING*2)*[[points objectAtIndex:index] floatValue]+PADDING));

        return CGPointMake(20+(space)*index, self.height-5-((self.height-PADDING*2)*[[points objectAtIndex:index] floatValue]));
    }
}

- (CGFloat)floatFromYValue:(CGFloat)yValue {
    
    return (self.height-((self.height-PADDING*2)*yValue+PADDING));
}

- (void)animate{
    
    if(self.detailView.superview)
        [self.detailView removeFromSuperview];
    
    gradient.hidden = NO;
    
    //    ((CAShapeLayer *)self.layer).fillColor = [UIColor clearColor].CGColor;
    ((CAShapeLayer *)self.layer).strokeColor = self.graphColor.CGColor;
    ((CAShapeLayer *)self.layer).path = [self graphPathFromPoints].CGPath;
    ((CAShapeLayer *)self.layer).lineWidth = self.lineWidth ? self.lineWidth : 1;
    
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.fromValue = @0;
    animation.toValue = @1;
    animation.duration = self.animationDuration;
    animation.delegate = self;
    [self.layer addAnimation:animation forKey:@"MPStroke"];
    
    for (UIButton* button in self.buttons) {
        [button removeFromSuperview];
    }
    
    CGFloat delay = ((CGFloat)self.animationDuration)/(CGFloat)points.count;
    
    if (_showPoints) {
        
        self.buttons = [[NSMutableArray alloc] init];
        for (NSInteger i = 0;i < points.count;i++) {
            
            CGPoint point = [self pointAtIndex:i];
            MPButton *button = [self customButtonWithIndex:i center:point];
            [self performSelector:@selector(displayPoint:) withObject:button afterDelay:delay*i];
            [self addSubview:button];
            
            [self.buttons addObject:button];
        }
    }
    
    
    if (_showTargetLine) {
        
        MPGraphValuesRange value = [MPPlot rangeForValues:self.values];
        CGFloat targetYValue = [self floatFromYValue:(_targetValue-value.min)/(value.max-value.min)];
        
        UIImageView *imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(0, targetYValue, self.frame.size.width, 2)];
        [self addSubview:imageView1];
        UIGraphicsBeginImageContext(imageView1.frame.size);   //开始画线
        [imageView1.image drawInRect:CGRectMake(0, 0, imageView1.frame.size.width, imageView1.frame.size.height)];
        CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);  //设置线条终点形状
        CGFloat lengths[] = {5,5};
        CGContextRef line = UIGraphicsGetCurrentContext();
        CGContextSetStrokeColorWithColor(line, self.graphColor.CGColor);
        CGContextSetLineDash(line, 0, lengths, 2);  //画虚线
        CGContextMoveToPoint(line, 0.0, 1);    //开始画线
        CGContextAddLineToPoint(line, 320, 1);
        CGContextStrokePath(line);
        imageView1.image = UIGraphicsGetImageFromCurrentImageContext();
    }
}

- (MPButton *)customButtonWithIndex:(NSInteger)i center:(CGPoint)point {
    
    MPButton *button = [MPButton buttonWithType:UIButtonTypeCustom];
    [button setBackgroundColor:[UIColor clearColor]];
    button.frame = CGRectMake(0, 0, 30, 30);
//    button.layer.cornerRadius = button.frame.size.width/2;
//    button.layer.borderWidth = 2;
//    button.layer.borderColor = [UIColor whiteColor].CGColor;
    
    CALayer *layer = [CALayer layer];
    layer.masksToBounds = YES;
    layer.borderWidth = 2;
    layer.borderColor = [UIColor whiteColor].CGColor;
    layer.backgroundColor = [UIColor clearColor].CGColor;
    layer.frame = CGRectMake(10, 10, 10, 10);
    layer.cornerRadius = layer.frame.size.width/2;
    [button.layer addSublayer:layer];
    
    if (_targetValue) {
        MPGraphValuesRange value = [MPPlot rangeForValues:self.values];
        CGFloat targetYValue = [self floatFromYValue:(_targetValue-value.min)/(value.max-value.min)];
        if (point.y <= targetYValue) {
            layer.borderColor = [UIColor greenColor].CGColor;
        }
        else
            layer.borderColor = [UIColor redColor].CGColor;
    }
    button.center = point;
    [button addTarget:self action:@selector(tap:) forControlEvents:UIControlEventTouchUpInside];
    button.tag = 200+i;
    button.transform = CGAffineTransformMakeScale(0,0);
    
    return button;
}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    
    self.waitToUpdate = NO;
    gradient.hidden = NO;
}


- (void)displayPoint:(UIButton *)button{
    
    [UIView animateWithDuration:.2 animations:^{
        button.transform = CGAffineTransformMakeScale(1, 1);
    }];
}


#pragma mark Setters

-(void)setFillColors:(NSArray *)fillColors{
    
    [gradient removeFromSuperlayer];
    gradient = nil;
    
    if(fillColors.count){
        
        NSMutableArray *colors=[[NSMutableArray alloc] initWithCapacity:fillColors.count];
        
        for (UIColor* color in fillColors) {
            if ([color isKindOfClass:[UIColor class]]) {
                [colors addObject:(id)[color CGColor]];
            }else{
                [colors addObject:(id)color];
            }
        }
        _fillColors=colors;
        
        gradient = [CAGradientLayer layer];
        gradient.frame = self.bounds;
        gradient.colors = _fillColors;
        [self.layer addSublayer:gradient];
        
        
    }else
        _fillColors = fillColors;
    
    [self setNeedsDisplay];
}

-(void)setCurved:(BOOL)curved{
    _curved = curved;
    [self setNeedsDisplay];
}



@end
